﻿module Program

open System.Collections.Generic
open Leaves.NeuroCryptography.NeuralNetworks
open Leaves.NeuroCryptography.KeyGenerators
open Leaves.NeuroCryptography.Cryptography
open Leaves.NeuroCryptography.Blocks
 
let PrintList (inputs : list<float>) =
    for value in inputs do
        printfn "%f" value

let RunFixed _ =
    let fixedHash = CreateFixedLengthHashFunction 12 32 "user key"

    let input = "Ivan Suhinin"
    let result = fixedHash input

    printf "Input:\t%s\nResult:\t%s\n" input result

let RunVariable _ =
    let fixedHash = CreateVariableLengthHashFunction 20 "user key variable ha"
    
    let inputs = [
        "Ivan";
        "Ivan ";
        "Ivan S";
        "Ivan Su";
        "Ivan Suh";
        "Ivan Suhi";
        "Ivan Suhin";
        "Ivan Suhini";
        "Ivan Suhinin";
        ]
    for input in inputs do
        let result = fixedHash input

        printf "Input:\t%s\nResult:\t%s\n\n" input result

let GetHammingDistance (first : string) (second : string) =
    if first.Length <> second.Length then
        failwith "wrong input lengths!"

    let mutable distance = 0
    for i in 0..(first.Length - 1) do
        if first.[i] <> second.[i] then
            distance <- distance + 1

    distance

let RunHammingTest _ =
    let fixedHash = CreateFixedLengthHashFunction 256 256 "User Key"

    let results = new Dictionary<int, int>()
    let initialInput = "Ivan Suhinin created this strjsalkdfjasxfoiwqejronjcv  m oiadjf oiwequrinin created thiwqerqwerwqerwqerweqrddckjncdmvniuowendneqwnjDSJAKFhasdreated this stringIvan Suhinin created this stringIvan Suhinin created this stringIvan Suhinin created this strinsg"

    for i in 0..(initialInput.Length - 1) do
        results.[i] <- 0

    let initialHash = fixedHash initialInput

    for i in 0..(initialInput.Length - 1) do
        let mutable minimumHammingDistance = initialInput.Length
        for letterIndex in 0..(InputAlphabet.Length - 1) do
            let replacement = InputAlphabet.[letterIndex]

            let newInput = initialInput.Substring(0, i) + InputAlphabet.[0].ToString() + initialInput.Substring(i + 1, initialInput.Length - i - 1)
            let newHash = fixedHash newInput

            let newHammingDistance = GetHammingDistance initialHash newHash

            if newHammingDistance < minimumHammingDistance then
                minimumHammingDistance <- newHammingDistance

        results.[i] <- minimumHammingDistance

    for i in 0..(initialInput.Length - 1) do
        printf "%d\t%d\n" i results.[i]

//    GetHammingDistance "Ivan" "IvAn"

[<EntryPoint>]
let main args =
    RunHammingTest()
//    RunFixed
//    RunVariable

//    let fixedHash = CreateFixedLengthHashFunction 32 32 "user key"
//
//    let input = "Ivan Suhinin created this hash!!"
//    let result = fixedHash input
//
//    printf "Input:\t%s\nResult:\t%s\n" input result

    0